mod utils;

use std::path::Path;
use tauri::{command, AppHandle, Emitter};

use utils::common;
use utils::server;

#[command]
fn get_app_dir() -> String {
    common::get_app_dir()
}

#[command]
fn test_connect(host: String, username: String, password: String) -> Result<(), String> {
    server::connect_server(host, username, password)?;
    Ok(())
}

#[command]
async fn upload_file(
    app: AppHandle,
    event_id: String,
    host: String,
    username: String,
    password: String,
    local_path: String,
    remote_path: String,
    before_script: String,
    after_script: String,
) -> Result<(), String> {
    let e = event_id.as_str();

    // 连接服务器
    app.emit(e, serde_json::json!({ "status": "connect_server", "p": 0 }))
        .unwrap();
    let sess = server::connect_server(host, username, password)?;
    app.emit(e, serde_json::json!({ "status": "connect_server", "p": 1 }))
        .unwrap();

    // 执行前置脚本
    if !before_script.is_empty() {
        app.emit(e, serde_json::json!({ "status": "before_script", "p": 0 }))
            .unwrap();
        let message = server::run_command(&sess, before_script)?;
        app.emit(
            e,
            serde_json::json!({ "status": "before_script", "p": 1, "data": message }),
        )
        .unwrap();
    }

    // 获取 SFTP 会话
    app.emit(e, serde_json::json!({ "status": "get_sftp", "p": 0 }))
        .unwrap();
    let sftp = server::get_sftp(&sess)?;
    app.emit(e, serde_json::json!({ "status": "get_sftp", "p": 1 }))
        .unwrap();

    // 上传文件
    app.emit(e, serde_json::json!({ "status": "upload_file", "p": 0 }))
        .unwrap();
    server::upload_file(&sftp, &local_path, &remote_path, |progress, cur, total| {
        let payload = serde_json::json!({
            "status": "upload_file",
            "p": progress / 100.0,
            "data": {
                "progress": progress,
                "cur": cur,
                "total": total
            }
        });
        app.emit(e, payload).unwrap();
    })?;
    app.emit(e, serde_json::json!({ "status": "upload_file", "p": 1 }))
        .unwrap();

    // 执行后置脚本
    if !after_script.is_empty() {
        app.emit(e, serde_json::json!({ "status": "after_script", "p": 0 }))
            .unwrap();
        let message = server::run_command(&sess, after_script)?;
        app.emit(
            e,
            serde_json::json!({ "status": "after_script", "p": 1, "data": message }),
        )
        .unwrap();
    }
    Ok(())
}

#[command]
fn download_dir_files(
    host: String,
    username: String,
    password: String,
    remote_path: String,
    backup_path: String,
) -> Result<(), String> {
    // 连接服务器
    let sess = server::connect_server(host, username, password)?;
    // 获取 SFTP 会话
    let sftp = server::get_sftp(&sess)?;
    // 下载远程目录文件到本地备份
    let remote_dir_path = Path::new(&remote_path);
    let backup_dir_path = Path::new(&backup_path);
    server::download_for_backup(&sftp, &remote_dir_path, &backup_dir_path)?;
    Ok(())
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_opener::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_fs::init())
        .invoke_handler(tauri::generate_handler![
            get_app_dir,        // 获取应用安装目录
            test_connect,       // 测试连接
            upload_file,        // 文件上传
            download_dir_files  // 远程文件夹下载备份
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
